/////////////////////////////////////////////////////////////////////////////
// Original code from libhdfs3. Copyright (c) 2013 - 2014, Pivotal Inc.
// All rights reserved. Author: Zhanwei Wang
/////////////////////////////////////////////////////////////////////////////
//  Modifications by Kumo Inc.
// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//



#pragma once


#include <kmhdfs/client/token.h>
#include <kmhdfs/server/datanode_info.h>
#include <kmhdfs/server/extended_block.h>

#include <vector>

namespace Hdfs {
namespace Internal {

/**
 * Associates a block with the Datanodes that contain its replicas
 * and other block metadata (E.g. the file offset associated with this
 * block, whether it is corrupt, security token, etc).
 */
class LocatedBlock: public ExtendedBlock {
public:
    LocatedBlock() :
        offset(0), corrupt(false), striped(false), lastBlock(false) {
    }

    LocatedBlock(int64_t position) :
        offset(position), corrupt(false), striped(false), lastBlock(false) {
    }

    bool isCorrupt() const {
        return corrupt;
    }

    void setCorrupt(bool corrupt) {
        this->corrupt = corrupt;
    }

    const std::vector<DatanodeInfo> & getLocations() const {
        return locs;
    }

    std::vector<DatanodeInfo> & mutableLocations() {
        return locs;
    }

    void setLocations(const std::vector<DatanodeInfo> & locs) {
        this->locs = locs;
    }

    int64_t getOffset() const {
        return offset;
    }

    void setOffset(int64_t offset) {
        this->offset = offset;
    }

    const Token & getToken() const {
        return token;
    }

    void setToken(const Token & token) {
        this->token = token;
    }

    bool operator <(const LocatedBlock & that) const {
        return this->offset < that.offset;
    }

    const std::vector<std::string> & getStorageIDs() const {
        return storageIDs;
    }

    std::vector<std::string> & mutableStorageIDs() {
        return storageIDs;
    }

    void setStorageIDs(const std::vector<std::string>& sid) {
        this->storageIDs = sid;
    }

    void setStriped(bool isStriped) {
        striped = isStriped;
    }

    bool isStriped() const {
        return striped;
    }
    
    const std::vector<int8_t> & getIndices() const {
        return indices;
    }

    std::vector<int8_t> & mutableIndices() {
        return indices;
    }

    std::vector<Token> & mutableTokens() {
        return tokens;
    }

    void setLastBlock(bool isLastBlock) {
        lastBlock = isLastBlock;
    }

    bool isLastBlock() const {
        return lastBlock;
    }

private:
    int64_t offset;
    bool corrupt;
    std::vector<DatanodeInfo> locs;
    std::vector<std::string> storageIDs;
    Token token;
    bool lastBlock;
    // for ec block
    bool striped;
    std::vector<int8_t> indices;
    std::vector<Token> tokens;
};

}
}
